package com.csx.governance.traffic.core.support;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import com.csx.governance.traffic.core.TrafficMessageParameterExtractor;
import com.csx.governance.traffic.core.context.TrafficMessage;
import com.csx.governance.traffic.core.context.webflux.TrafficWebFluxRequest;
import org.springframework.http.HttpHeaders;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.util.LinkedCaseInsensitiveMap;
import org.springframework.web.server.ServerWebExchange;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>Http请求头解析器</p>
 * <p>解析 {@link ServerWebExchange} 中Header的解析器，主要作用是将 {@link ServerWebExchange}中的Header放入到一个Map中</p>
 * @author cuisongxu
 * @date 2023/4/12 15:25
 */
public class HttpReactiveRequestHeaderExtractor implements TrafficMessageParameterExtractor {

    @Override
    public Map<String, Object> extract(TrafficMessage trafficMessage) {
        ServerHttpRequest originRequest = trafficMessage.getOriginMessage(ServerHttpRequest.class);
        Assert.notNull(originRequest, "current HttpReactiveRequestHeaderExtractor not support this request type: " + trafficMessage);

        Map<String, Object> headers = new LinkedCaseInsensitiveMap<>();
        HttpHeaders httpHeaders = originRequest.getHeaders();
        Map<String, String> temp = new HashMap<>(16);
        for (Map.Entry<String, List<String>> entry : httpHeaders.entrySet()) {
            String key = entry.getKey();
            List<String> values = entry.getValue();
            String value = null;
            if(!CollectionUtil.isEmpty(values)) {
                value = values.get(0);
            }
            if(StrUtil.isNotEmpty(key) && StrUtil.isNotEmpty(value)) {
                temp.put(key, value);
            }
        }
        headers.putAll(temp);
        return headers;
    }

    @Override
    public Boolean isSupport(Class<?> clazz) {
        return clazz.equals(TrafficWebFluxRequest.class);
    }

    @Override
    public ParameterSource parameterSource() {
        return ParameterSource.HEADER;
    }
}
